﻿/*
 * @author: wizardc
 */

using UnityEngine;
using UnityEngine.UI;

namespace Dou.UI
{
    public static class UIUtil
    {
        /// <summary>
        /// 设置 Canvas 的层级
        /// </summary>
        public static void SetOrder(this Canvas canvas, int order)
        {
            var component = canvas.GetComponent<UISortingOrderController>();
            if (component == null)
            {
                canvas.overrideSorting = true;
                canvas.sortingOrder = order;
            }
            else
            {
                component.localOrder = order;
            }
        }

        /// <summary>
        /// UI 本地坐标点转对应世界坐标点
        /// </summary>
        public static Vector3 LocalPointInRectangleToWorldPoint(RectTransform rect, Vector2 localPoint)
        {
            return rect.TransformPoint(localPoint);
        }
        
        /// <summary>
        /// 世界坐标点转对应 UI 本地坐标点
        /// </summary>
        public static bool WorldPointToLocalPointInRectangle(RectTransform rect, Vector3 worldPoint, Camera camera, out Vector2 localPoint)
        {
            var screenPoint = RectTransformUtility.WorldToScreenPoint(camera, worldPoint);
            return RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, screenPoint, camera, out localPoint);
        }

        /// <summary>
        /// 将 UI(originRect) 下的本地坐标转换为 UI(targetRect) 下对应位置的本地坐标
        /// 注意 2 个 UI 必须位于同一个摄像机下
        /// </summary>
        public static bool GetLocalPointInOtherRectangle(RectTransform originRect, Vector2 originLocalPoint, RectTransform targetRect, Camera camera, out Vector2 localPoint)
        {
            var worldPoint = originRect.TransformPoint(originLocalPoint);
            var screenPoint = RectTransformUtility.WorldToScreenPoint(camera, worldPoint);
            return RectTransformUtility.ScreenPointToLocalPointInRectangle(targetRect, screenPoint, camera, out localPoint);
        }

        /// <summary>
        /// 重建布局
        /// </summary>
        public static void RebuildLayout(RectTransform rect, bool immediate = true)
        {
            if (immediate)
            {
                LayoutRebuilder.ForceRebuildLayoutImmediate(rect);
            }
            else
            {
                LayoutRebuilder.MarkLayoutForRebuild(rect);
            }
        }
        
        /// <summary>
        /// 指定节点下的所有 UI 置灰
        /// </summary>
        public static void SetGray(Transform root, bool isGray)
        {
            {
                var images = root.GetComponents<DImage>();
                foreach (var image in images)
                {
                    image.useGray = isGray;
                }
                var rawImages = root.GetComponents<DRawImage>();
                foreach (var rawImage in rawImages)
                {
                    rawImage.useGray = isGray;
                }
                var texts = root.GetComponents<DText>();
                foreach (var text in texts)
                {
                    text.useGray = isGray;
                }
                var textMeshes = root.GetComponents<DTextMeshProUGUI>();
                foreach (var textMesh in textMeshes)
                {
                    textMesh.useGray = isGray;
                }
            }
            {
                var images = root.GetComponentsInChildren<DImage>(true);
                foreach (var image in images)
                {
                    image.useGray = isGray;
                }
                var rawImages = root.GetComponentsInChildren<DRawImage>(true);
                foreach (var rawImage in rawImages)
                {
                    rawImage.useGray = isGray;
                }
                var texts = root.GetComponentsInChildren<DText>(true);
                foreach (var text in texts)
                {
                    text.useGray = isGray;
                }
                var textMeshes = root.GetComponentsInChildren<DTextMeshProUGUI>(true);
                foreach (var textMesh in textMeshes)
                {
                    textMesh.useGray = isGray;
                }
            }
        }
        
        /// <summary>
        /// 获取系统输入框的高度（屏幕坐标系下）
        /// </summary>
        public static float GetKeyboardHeight()
        {
#if UNITY_EDITOR
            return 0;
#endif
            
#if UNITY_ANDROID
        using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            var unityPlayer = unityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer");
            var view = unityPlayer.Call<AndroidJavaObject>("getView");
            var dialog = unityPlayer.Get<AndroidJavaObject>("mSoftInputDialog");
            if (view == null || dialog == null)
            {
                return -1;
            }
            var decorHeight = 0;
            var decorView = dialog.Call<AndroidJavaObject>("getWindow").Call<AndroidJavaObject>("getDecorView");
            if (decorView != null)
            {
                decorHeight = decorView.Call<int>("getHeight");
            }
            using (var rect = new AndroidJavaObject("android.graphics.Rect"))
            {
                view.Call("getWindowVisibleDisplayFrame", rect);
                return Display.main.systemHeight - rect.Call<int>("height") + decorHeight;
            }
        }
#else
            var height = Mathf.RoundToInt(TouchScreenKeyboard.area.height);
            return height >= Display.main.systemHeight ? 0 : height;
#endif
        }
    }
}
